<?php

abstract class AMapper
{

	// TODO: Automatic version control
	// Best way is probably to wrap update calls and check
	// the number of modified rows - Probably won't go in
	// here but in DBConn instead

	public static function &_get($in_caller)
	{
		$caller_instance = call_user_func(array($in_caller,'getSelf'));
		if (!($caller_instance instanceof AMapper))
		{
			call_user_func(array($in_caller,'setSelf'),new $in_caller());
		}
		return call_user_func(array($in_caller,'getSelf'));
	}

	public function findAll($in_start=0, $in_limit=0)
	{
		$entity = substr(__CLASS__,0,-6);
		$qry = "SELECT * FROM " . strtolower($entity) . "s";
		if(is_numeric($in_start) && is_numeric($in_limit) && ($in_start || $in_limit))
		{
			$qry .= " LIMIT " . $in_start . "," . $in_limit;
		}
		$data = DBConn::selectAll($qry);
		$objects = array();
		foreach($data as $row)
		{
			$this->load($row);
		}
		return $objects;
	}
	public function automaticFind($in_id)
	{
		$entity = substr(__CLASS__,0,-6);
		if(is_numeric($in_id))
		{
			$qry = "SELECT * FROM " . strtolower($entity) . "s WHERE " . $entity . "_id = " . $in_id;
			$data = DBConn::selectRow($qry);
			return $this->load($data);
		}
		else
		{
			throw new PlatformInvalidModelArgumentsException("The id provided was not a number");
		}
	}

	public function automaticInsert(&$in_entity)
	{
		$insertlist = self::makeInsertSQL($in_entity);
		$sql = "INSERT INTO ".$in_entity->getTable().$insertlist;
		if ($in_entity->isRevisable())
			$this->assignRevision($in_entity);

		return DBConn::insert($sql);
	}

	private static function makeInsertSQL(&$in_entity)
	{
		$values = array();
		foreach ($in_entity->getFields() as $fieldname)
		{
			$values[] = DBConn::quote($in_entity->get($fieldname));
		}
		return ' (' . implode(',',$in_entity->getFields()) . ') VALUES (' . implode(',',$values) . ')';
	}

	public function automaticUpdate(&$in_entity)
	{
		$updatelist = self::makeUpdateSQL($in_entity);
		$sql = "UPDATE ".$in_entity->getTable()." SET ".$updatelist." WHERE " . $in_entity->getIdField() . " = ".$in_entity->get($in_entity->getIdField());
		try
		{
			DBConn::exec($sql);
		}
		catch (Exception $e)
		{
			die('i has excepted! '.get_class($e).' -> '.$e->getMessage());
		}
	}

	private static function makeUpdateSQL(&$in_entity)
	{
		$updates = array();
		foreach ($in_entity->getFields() as $fieldname)
		{
			$updates[] = $fieldname.'='.DBConn::quote($in_entity->get($fieldname));
		}
		return implode(',',$updates);
	}
}

class PlatformInvalidModelArgumentsException extends Exception {}

?>
